#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

// 1.创建的多个线程并不保证哪个线程先运行
// 2.不能用全局变量代替线程函数的参数
// 3.不能使用相同的地址代替线程函数的参数
// 4.正确的整型参数传递，强制类型转换
// 5.正确的地址参数传递，给每个线程一个地址

void *thmain1(void *arg); // 线程1的主函数
void *thmain2(void *arg); // 线程2的主函数
void *thmain3(void *arg); // 线程3的主函数
void *thmain4(void *arg); // 线程4的主函数
void *thmain5(void *arg); // 线程5的主函数

int var;

int main(int argc, char *argv[])
{
    // 3.强制类型转换
    // int i = 10;
    // void *pv = 0;
    // pv = (void*)(long)i;
    // printf("pv=%p\n", pv);

    // int j = 0;
    // j = (int)(long)pv;
    // printf("j=%d\n", j);

    // return 0;

    pthread_t thid1 = 0, thid2 = 0, thid3 = 0, thid4 = 0, thid5 = 0;

    // var = 1;
    // if (pthread_create(&thid1, NULL, thmain1, NULL) != 0)            // 1.不能使用全局变量
    // if (pthread_create(&thid1, NULL, thmain1, &var) != 0)            // 2.不能使用直接传地址，在本质上与使用全局变量相同
    // if (pthread_create(&thid1, NULL, thmain1, (void*)(long)var) != 0)// 3.整型参数的传递
    int *var1 = new int;                                                // 4.地址参数的传递，给每个线程一个地址
    *var1 = 1;
    if (pthread_create(&thid1, NULL, thmain1, var1) != 0)
    {
        printf("pthread_create failed.\n");
        exit(-1);
    }


    // var = 2;
    // if (pthread_create(&thid2, NULL, thmain2, NULL) != 0)
    // if (pthread_create(&thid2, NULL, thmain2, &var) != 0)
    // if (pthread_create(&thid2, NULL, thmain2, (void*)(long)var) != 0)
    int *var2 = new int;
    *var2 = 2;
    if (pthread_create(&thid2, NULL, thmain2, var2) != 0)
    {
        printf("pthread_create failed.\n");
        exit(-1);
    }


    // var = 3;
    // if (pthread_create(&thid3, NULL, thmain3, NULL) != 0)
    // if (pthread_create(&thid3, NULL, thmain3, &var) != 0)
    // if (pthread_create(&thid3, NULL, thmain3, (void*)(long)var) != 0)
    int *var3 = new int;
    *var3 = 3;
    if (pthread_create(&thid3, NULL, thmain3, var3) != 0)
    {
        printf("pthread_create failed.\n");
        exit(-1);
    }

    
    // var = 4;
    // if (pthread_create(&thid4, NULL, thmain4, NULL) != 0)
    // if (pthread_create(&thid4, NULL, thmain4, &var) != 0)
    // if (pthread_create(&thid4, NULL, thmain4, (void*)(long)var) != 0)
    int *var4 = new int;
    *var4 = 4;
    if (pthread_create(&thid4, NULL, thmain4, var4) != 0)
    {
        printf("pthread_create failed.\n");
        exit(-1);
    }

    
    // var = 5;
    // if (pthread_create(&thid5, NULL, thmain5, NULL) != 0)
    // if (pthread_create(&thid5, NULL, thmain5, &var) != 0)
    // if (pthread_create(&thid5, NULL, thmain5, (void*)(long)var) != 0)
    int *var5 = new int;
    *var5 = 5;
    if (pthread_create(&thid5, NULL, thmain5, var5) != 0)
    {
        printf("pthread_create failed.\n");
        exit(-1);
    }

    // 等待子线程退出。
    printf("join...\n");
    pthread_join(thid1, NULL);
    pthread_join(thid2, NULL);
    pthread_join(thid3, NULL);
    pthread_join(thid4, NULL);
    pthread_join(thid5, NULL);
    printf("join ok.\n");
}

void *thmain1(void *arg)
{
    // printf("var1=%d\n", var);                // 1.不能使用全局变量
    // printf("var1=%d\n", *(int *)arg);        // 2.传地址在本质上与使用全局变量相同
    // printf("var1=%d\n", (int)(long)arg);     // 3.整型参数的传递
    printf("var1=%d\n", *(int *)arg);           // 4.地址参数的传递
    delete (int *)arg;                          // 释放内存的代码放在线程的主函数中
    printf("线程1开始运行。\n");
}

void *thmain2(void *arg)
{
    // printf("var2=%d\n", var);
    // printf("var2=%d\n", *(int *)arg);
    // printf("var2=%d\n", (int)(long)arg);
    printf("var2=%d\n", *(int *)arg);
    delete (int *)arg;
    printf("线程2开始运行。\n");
}

void *thmain3(void *arg)
{
    // printf("var3=%d\n", var);
    // printf("var3=%d\n", *(int *)arg);
    // printf("var3=%d\n", (int)(long)arg);
    printf("var3=%d\n", *(int *)arg);
    delete (int *)arg;
    printf("线程3开始运行。\n");
}

void *thmain4(void *arg)
{
    // printf("var4=%d\n", var);
    // printf("var4=%d\n", *(int *)arg);
    // printf("var4=%d\n", (int)(long)arg);
    printf("var4=%d\n", *(int *)arg);
    delete (int *)arg;
    printf("线程4开始运行。\n");
}

void *thmain5(void *arg)
{
    // printf("var5=%d\n", var);
    // printf("var5=%d\n", *(int *)arg);
    // printf("var5=%d\n", (int)(long)arg);
    printf("var5=%d\n", *(int *)arg);
    delete (int *)arg;
    printf("线程5开始运行。\n");
}
